package com.zysc.processflow.controller;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zysc.processflow.common.base.ResultBody;
import com.zysc.processflow.common.util.StringUtils;
import com.zysc.processflow.entity.Organization;
import com.zysc.processflow.entity.Person;
import com.zysc.processflow.service.IOrganizationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import com.zysc.processflow.common.base.BaseController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 组织机构表 前端控制器
 * </p>
 *
 * @author 正元智慧城市_
 * @since 2022-11-18
 */
@Api(value = "组织机构", tags = "组织机构")
@RestController
@RequestMapping("/organization")
public class OrganizationController extends BaseController<Organization> {

    @Autowired
    IOrganizationService service;

    public OrganizationController(IOrganizationService service) {
        super(service);
    }

    @ApiOperation("获取组织机构列表(支持分页)")
    @GetMapping(value = "GetOrganizationList")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "pageIndex", name = "pageIndex", dataType = "String"),
            @ApiImplicitParam(value = "pageSize", name = "pageSize", dataType = "String"),
            @ApiImplicitParam(value = "名称", name = "name", dataType = "String"),
            @ApiImplicitParam(value = "只查企业flag", name = "qyflag", dataType = "String"),
            @ApiImplicitParam(value = "区县", name = "district", dataType = "String"),
            @ApiImplicitParam(value = "类型", name = "type", dataType = "String"),
            @ApiImplicitParam(value = "上级名称", name = "fathername", dataType = "String"),
    })
    public ResultBody GetOrganizationList(Integer pageIndex , Integer pageSize , String name,String qyflag,String district,String type,String fathername) {
        if (pageIndex != null && pageSize != null) {
            IPage<Organization> page = new Page<>(pageIndex, pageSize);
            List<Organization> res = service.GetOrganizationListByPage(page, name,qyflag,district,type,fathername);
            return ResultBody.Success(res, page.getTotal());
        } else {
            List<Organization> res = service.GetOrganizationListByPage(null, name,qyflag,district,type,fathername);
            return ResultBody.Success(res);
        }
    }


    @ApiOperation("根据id获取组织机构信息")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "id", name = "id", dataType = "String")
    })
    @GetMapping("GetOrganizationDataById")
    public ResultBody GetOrganizationDataById(String id){
        return ResultBody.Success(service.getById(id) );
    }


    @ApiOperation("查询当前组织及其下属部门(如果有)的用户")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "id", name = "id", dataType = "String")
    })
    @GetMapping("/GetAllUserinfoByOrgid")
    public ResultBody GetAllUserinfoByOrgid(String id){
        List<Person> res = service.GetAllUserinfoByOrgid(id);
        return ResultBody.Success(res);
    }

    @ApiOperation("传入orgid,返回从根到orgid的数组")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "组织机构id", name = "orgid", dataType = "String")
    })
    @GetMapping("/GetOwnerArray")
    public ResultBody GetOwnerArray(String orgid,String currentorgid){
        List<String> res = service.getOwnerArray(orgid,currentorgid);
        return ResultBody.Success(res);
    }


    @ApiOperation("获取所有的后代组织机构")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "组织机构id", name = "orgid", dataType = "String")
    })
    @GetMapping("/getChildrenOrg")
    public ResultBody getChildrenOrg(String orgid){
        List<Organization> res = service.getChildrenOrg(orgid);
        return ResultBody.Success(res);
    }

    //向下递归获取全部子级构建树。
    private void treedata(List<Organization> rs, Organization pm) {
        for (Organization m : rs) {
            if (pm.getId() != null && pm.getId().equals(m.getFatherid())) {
                List<Organization> childs = pm.getChildren();
                if(childs==null){
                    childs = new ArrayList<>();
                    pm.setChildren(childs);
                }
                childs.add(m);
                treedata(rs, m);
            }
        }
    }
    //向上递归获取全部上级列表。
    private void getParents(List<Organization> all, Organization child, List<Organization> results) {
        Optional<Organization> op = all.stream().filter(item -> item.getId().equals(child.getFatherid())).findFirst();
        if (op.isPresent()) {
            Organization oo = op.get();
            Optional opp = results.stream().filter(r -> r.getId().equals(oo.getId())).findAny();
            if (!opp.isPresent()) {// 没在结果中就添加，在结果集中证明该节点及其父辈节点都在结果集中。
                results.add(oo);
                getParents(all, oo, results);
            }
        }
    }

    @ApiOperation("分页查询组织机构")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "pageSize", name = "pageSize", dataType = "Integer"),
            @ApiImplicitParam(value = "pageIndex", name = "pageIndex", dataType = "Integer"),
            @ApiImplicitParam(value = "类型", name = "type", dataType = "String"),
            @ApiImplicitParam(value = "代码", name = "code", dataType = "String"),
            @ApiImplicitParam(value = "名称", name = "name", dataType = "String"),
            @ApiImplicitParam(value = "当前的组织机构id", name = "currentorgid", dataType = "String"),
            @ApiImplicitParam(value = "当前的组织机构类型", name = "currentorgtype", dataType = "String"),
    })
    @GetMapping("PagingQuery")
    public ResultBody pagequery(Integer pageSize, Integer pageIndex, String type, String code, String name, String currentorgid, String currentorgtype) {
        List<Organization> alllist = new ArrayList<>();
        if(StringUtils.isNull(currentorgid)){
            //alllist = service.list();
            return ResultBody.Success(alllist);
        }else{
            alllist = service.getAllOrgFlowedByorgId(currentorgid,currentorgtype);
        }
        List<Organization> results = new ArrayList<>(), tmplist = new ArrayList<>();
        // 条件过滤。查询符合条件的节点列表。默认没有符合条件的选择全部。
        for(Organization item:alllist){
            Boolean b = null;
            if (type != null && !type.isEmpty()){
                if(StringUtils.isNull(item.getType())){
                    continue;
                }
                b = item.getType().equals(type);
                if(!b)continue;
            }
            if (code != null && !code.isEmpty()){
                if(StringUtils.isNull(item.getCode())){
                    continue;
                }
                b = item.getCode().indexOf(code) > -1;
                if(!b)continue;
            }
            if (name != null && !name.isEmpty()){
                if(StringUtils.isNull(item.getName())){
                    continue;
                }
                b = item.getName().indexOf(name) > -1;
                if(!b)continue;
            }
            if(b!=null && b==true){
                tmplist.add(item);
            }
        }
        //先找出了符合条件的大的小的都有，不分
        if (tmplist.size() > 0) {
            for (Organization org : tmplist) {
                results.add(org);//将当前节点添加到结果集中。
                this.getParents(alllist, org, results);//把节点的所有父节点也加入进来
            }
        } else {
            if (StringUtils.isNull(type) && StringUtils.isNull(name) && StringUtils.isNull(code)) {
                results=alllist;
            }else{
                return ResultBody.Success(new ArrayList<Organization>());
            }

        }

        //获取根节点
        List<Organization> roots = new ArrayList<>();
        if(StringUtils.isNull(currentorgid)){
            roots = results.stream().filter(item -> item.getFatherid() == null || item.getFatherid().isEmpty()).collect(Collectors.toList());
        }else{
            for(int i = 0;i<results.size();i++){
                Organization item = results.get(i);
                String fatherid = item.getFatherid();
                Boolean flag = true;//判断这个组织机构的父节点有没有在这些里边，如果没有，那么他就是root节点
                for(int j = 0;j<results.size();j++){
                    Organization temp = results.get(j);
                    String id = temp.getId();
                    if(!StringUtils.isNull(fatherid) && fatherid.equals(id)){
                        flag=false;
                        break;
                    }
                }
                if(flag){
                    roots.add(item);
                }
            }
        }
        roots.sort((Organization a, Organization b) -> {
            if (a.getCreatetime()!=null && b.getCreatetime()!=null && a.getCreatetime() > b.getCreatetime()) {
                return 1;
            } else {
                return -1;
            }
        });
        //  分业。 获取子节点组装树。
        if (pageIndex != null && pageSize != null) {
            Long total = Long.valueOf(roots.size());
            List<Organization> res = new ArrayList<>();
            for (int i = pageSize * (pageIndex - 1); i < pageIndex * pageSize && i < total; i++) {
                Organization org = roots.get(i);
                res.add(org);
                treedata(results, org);
            }
            return ResultBody.Success(res, total);
        } else {
            for (Organization org : roots) {
                treedata(results, org);
            }
            return ResultBody.Success(roots);
        }
    }

    @ApiOperation("删除组织机构")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "组织机构实体", name = "entity", dataType = "Organization")
    })
    @PostMapping("Remove")
    public ResultBody remove(@RequestBody Organization entity) {
        Boolean b = service.removeById(entity.getId());
        return ResultBody.Success(b);
    }

    @ApiOperation("添加/更新组织机构")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "组织机构信息", name = "entity", dataType = "Organization")
    })
    @Transactional
    @PostMapping(value = "SaveOrUpdate")
    public ResultBody SaveOrUpdate(@RequestBody Organization entity) {
        try{
            Boolean b = service.saveOrUpdateOrgnInfo(entity);
            if(!b){
                throw new RuntimeException("保存组织机构信息失败!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultBody.error(e.getMessage(), 500);
        }
        return ResultBody.Success(entity);
    }



    //因为组织机构的信息，多半是外部接口传来的，别公司在传数据的时候，如果先传子部门，后来传父部门，那么子部门的fatherName会查不到所以不显示。path字段也是
    //可以在传完数据后如果数据有异常，那么可以调这个接口更新一下全部数据
    @ApiOperation("完善数据信息fatherName和path等")
    @ApiImplicitParams({
    })
    @Transactional
    @GetMapping(value = "updateFatherNameAndPath")
    public ResultBody updateFatherNameAndPath() {
        try{
            Boolean b = service.updateFatherNameAndPath();
            if(!b){
                throw new RuntimeException("更新完善组织机构信息失败!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultBody.error(e.getMessage(), 500);
        }
        return ResultBody.Success(null);
    }


    @ApiOperation("传入orgid,获取子节点的数据列表")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "组织机构id", name = "orgid", dataType = "String")
    })
    @GetMapping("/GetSonNodeById")
    public ResultBody GetSonNodeById(String orgid){
        List<Map> res = service.GetSonNodeById(orgid);
        return ResultBody.Success(res);
    }

    @ApiOperation("模糊查询根据列")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "pageIndex", name = "pageIndex", dataType = "String"),
            @ApiImplicitParam(value = "pageSize", name = "pageSize", dataType = "String"),
            @ApiImplicitParam(value = "查询列", name = "queryColomnList", dataType = "List"),
            @ApiImplicitParam(value = "关键字", name = "keyword", dataType = "String"),
            @ApiImplicitParam(value = "精准查询", name = "precise", dataType = "Boolean"),
    })
    @GetMapping("/getOrgDataListByKeyword")
    public ResultBody getOrgDataListByKeyword(
            @RequestParam(value = "pageIndex",required = false)Integer pageIndex ,
            @RequestParam(value = "pageSize",required = false)Integer pageSize ,
            @RequestParam(value = "queryColomnList",required = false) List<String> queryColomnList,
            @RequestParam(value = "keyword",required = false) String keyword,
            @RequestParam(value = "precise",required = false) Boolean precise
    ){
        if (pageIndex != null && pageSize != null) {
            IPage<Organization> page = new Page<>(pageIndex, pageSize);
            List<Organization> res = service.getOrgDataListByKeyword(page, queryColomnList,keyword,precise);
            return ResultBody.Success(res, page.getTotal());
        } else {
            List<Organization> res = service.getOrgDataListByKeyword(null,queryColomnList,keyword,precise);
            return ResultBody.Success(res);
        }
    }

    @ApiOperation("getOrgDataTest")
    @ApiImplicitParams({
    })
    @GetMapping("/getOrgDataTest")
    public ResultBody getOrgDataTest(){
        List<Organization> res=  service.getTestData();
        return ResultBody.Success(res, (long) res.size());
    }

}
